# 导入Flask类
from flask import Flask
from flask import render_template,request
from datetime import datetime
import os
import requests
import subprocess
import time


#Flask类接收一个参数__name__
app = Flask(__name__)

#生成文件树
def generate_file_tree(path):
    root = {
        'name': os.path.basename(path),
        'type': 'directory',
        'children': []
    }
    for item in os.listdir(path):
        item_path = os.path.join(path, item)
        if os.path.isdir(item_path):
            child = generate_file_tree(item_path)
        else:
            # 获取文件的修改时间
            modified_time = os.path.getmtime(item_path)
            # 将时间戳格式化为年月日时分秒
            formatted_time = datetime.fromtimestamp(modified_time).strftime('%Y-%m-%d %H:%M:%S')
            # 获取文件的大小并转换为MB
            file_size = os.path.getsize(item_path) / 1024
            # 带上 MB 单位
            file_size_str = f"{file_size:.2f}KB"
            child = {
                'name': item,
                'type': 'file',
                'path': item_path,
                'modified_time': formatted_time,
                'size_mb': file_size_str
            }
        root['children'].append(child)
    return root

# 根目录
@app.route('/')
def index():
    return 'Hello 341'

# 根目录
@app.route('/task')
def taskIndex():
    return render_template("task.html")

# 根目录
@app.route('/begin')
def beginIndex():


    return render_template("begin.html")


# 声明全局变量
lidar_process = None
mid360_process = None
camera_process = None
recording_process = None


# 根目录
@app.route('/processing')
def processingIndex():
    global lidar_process, mid360_process, camera_process, recording_process

    home_dir = os.path.expanduser("~")
    log_dir = os.path.join(home_dir, "log")
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)
    
    stdout_path1 = os.path.join(log_dir, "lidar_output.log")
    stderr_path1 = os.path.join(log_dir, "lidar_error.log")

    stdout_path2 = os.path.join(log_dir, "mid360_output.log")
    stderr_path2 = os.path.join(log_dir, "mid360_error.log")

    stdout_path3 = os.path.join(log_dir, "camera_output.log")
    stderr_path3 = os.path.join(log_dir, "camera_error.log")

    stdout_path4 = os.path.join(log_dir, "recording_output.log")
    stderr_path4 = os.path.join(log_dir, "recording_error.log")

    env = os.environ.copy()
    env["NO_COLOR"] = "1"

    # 启动激光雷达
    try:
        with open(stdout_path1, 'w') as stdout_file, open(stderr_path1, 'w') as stderr_file:
            lidar_process = subprocess.Popen(['bash', '-c', ". ~/livox_ws/devel/setup.bash && roslaunch livox_ros_driver2 msg_MID360.launch"], stdout=stdout_file, stderr=stderr_file, universal_newlines=True)
        print("打开激光雷达")
    except subprocess.CalledProcessError as e:
        print(f"命令执行出错: {e.stderr}")
    except Exception as e:
        print(f"打开终端时出错: {e}")

    # 休息5秒 避免mindao360报错
    time.sleep(5)

    # 启动mid360
    try:
        with open(stdout_path2, 'w') as stdout_file, open(stderr_path2, 'w') as stderr_file:
            mid360_process = subprocess.Popen(['bash', '-c', ". ~/fast_lio_ws/devel/setup.bash && roslaunch fast_lio mapping_mid360.launch"], stdout=stdout_file, stderr=stderr_file, universal_newlines=True)
        print("启动建图")
    except subprocess.CalledProcessError as e:
        print(f"命令执行出错: {e.stderr}")
    except Exception as e:
        print(f"打开终端时出错: {e}")

    # 休息5秒
    time.sleep(5)

    # 打开摄像头
    try:
        with open(stdout_path3, 'w') as stdout_file, open(stderr_path3, 'w') as stderr_file:
            camera_process = subprocess.Popen(['bash', '-c', ". ~/ros_ws/devel/setup.bash && roslaunch astra_camera astra_pro_plus.launch"], stdout=stdout_file, stderr=stderr_file, universal_newlines=True)
        print("启动摄像头")
    except subprocess.CalledProcessError as e:
        print(f"命令执行出错: {e.stderr}")
    except Exception as e:
        print(f"打开终端时出错: {e}")

    # 休息1秒
    time.sleep(1)

    # 录制
    try:
        with open(stdout_path4, 'w') as stdout_file, open(stderr_path4, 'w') as stderr_file:
            recording_process = subprocess.Popen(['bash', '-c', ". ~/camera_recording_ws/devel/setup.bash && rosrun video_recorder recording_node"], stdout=stdout_file, stderr=stderr_file, universal_newlines=True)
        print("启动录制")
    except subprocess.CalledProcessError as e:
        print(f"命令执行出错: {e.stderr}")
    except Exception as e:
        print(f"打开终端时出错: {e}")

    return render_template("processing.html")

# 根目录
@app.route('/end')
def endIndex():
    global lidar_process, mid360_process, camera_process, recording_process

    processes = [lidar_process, mid360_process, camera_process, recording_process]

    for process in processes:
        if process and process.poll() is None:  # 检查进程是否正在运行
            try:
                process.terminate()  # 尝试正常终止进程
                process.wait(timeout=5)  # 等待进程在 5 秒内终止
            except subprocess.TimeoutExpired:
                process.kill()  # 若超时，强制终止进程
                process.wait()  # 等待进程退出
    print("正常结束,pcd文件保存到/home/dzyl/Data/PCD")
    print("正常结束,avi文件保存到/home/dzyl/Data/video")
    print("------处理PCD文件------")
    recording_process = subprocess.Popen(['bash','-c',  "cd ~/pcd_v3/build/ && ./pcd_filter_v2"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
    print("----处理完成--------")
    #pcd文件路径
    # path = 'D:\\project'
    path = '/home/dzyl/Data/PCD'
    file_tree = generate_file_tree(path)
    return render_template("end.html",file_tree=file_tree,path=path)



# 上传操作页面
@app.route('/upload')
def upload():
    #pcd文件路径
    path = '/home/dzyl/Data/PCD'

    #视频文件路径
    path1 = '/home/dzyl/Data/video'

    #txt文件
    path2 = '/home/dzyl/Data/Filtered_Txt'

    file_tree = generate_file_tree(path)
    file_tree1 = generate_file_tree(path1)
    file_tree2 = generate_file_tree(path2)
    return render_template("base.html",file_tree=file_tree,path=path,file_tree1=file_tree1,path1=path1, file_tree2=file_tree2,path2=path2)

@app.route('/upload-to-remote', methods=['POST'])
def upload_to_remote():
    file_paths = request.form.getlist('file')
    for file_path in file_paths:
        print(f"File {file_path} uploading.")
        if os.path.exists(file_path):
            with open(file_path, 'rb') as file:
                files = {'file': file}
                try:
                    # 添加请求头
                    headers = {
                        'tenant-id': '1'
                    }
                    response = requests.post('https://mlr.tgsc81.com:5341/app-api/infra/file/upload', files=files,headers=headers)
                    response.raise_for_status()
                    print(f"File {file_path} uploaded successfully.")
                    return response.text, 200
                except requests.RequestException as e:
                    print(f"Error uploading file {file_path}: {e}")
                    return f"Request error: {str(e)}", 500
        else:
            print(f"File {file_path} uploaded fail.")
            return "File not found.", 404


# Flask应用程序实例的run方法启动WEB服务器
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)  # 设置 host 为 '0.0.0.0'，并指定端口为 5000
